package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.article.service.ArticleBehaviorService;
import com.heima.common.constants.HotArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleBehaviorDto;
import com.heima.model.article.dtos.CollectionDto;
import com.heima.model.article.vos.ArticleBehaviorVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.utils.thread.AppUserThreadLocalUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class ArticleBehaviorServiceImpl implements ArticleBehaviorService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 加载文章操作详情 数据回显
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult loadArticleBehavior(ArticleBehaviorDto dto) {
        //1、参数校验
        if (dto == null || dto.getArticleId() == null || dto.getAuthorId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、首先得到当前用户id
        Integer userId = AppUserThreadLocalUnit.get();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        // 满参构造返回值（默认值）
        ArticleBehaviorVo articleBehaviorVo = new ArticleBehaviorVo();
       /* //2.2、在redis里读取该用户在该文章下的所有行为集合
          Map<String, Integer> map = (Map<String, Integer>) redisTemplate.opsForValue().get(userId + "_" + dto.getArticleId());
        if (map == null) {
            //就是第一次该用户第一次点进来啥都还没干 直接返回全部默认值
            return ResponseResult.okResult(articleBehaviorVo);
        }
        // 2.3、是否点赞
        Integer operation1 = map.get("operation");
        if (operation1 != null) {
            //点赞了
            if (operation1 == 0) {
                articleBehaviorVo.setIslike(true);
            }
        }
        //2.4、是否不喜欢
        Integer type = map.get("unlike");
        if (type != null) {
            //不喜欢
            if (type == 0) {
                articleBehaviorVo.setIsunlike(true);
            }
        }
        //2.5、是否关注
        //先取出该用户id对应的关注列表
        List<Integer> idols = (List<Integer>) redisTemplate.opsForValue().get(userId.toString());
        //判断关注列表是否包含作者id
        if (idols != null) {
            //非空
            if (idols.contains(dto.getAuthorId())) {
                // 包含该作者
                articleBehaviorVo.setIsfollow(true);
            }
        }
        //2.6、
        Integer operation = (Integer) redisTemplate.opsForValue().get(dto.getArticleId() + "_" + userId);
        if (operation != null) {
            //非空
            if (operation == 0) {
                //关注
                articleBehaviorVo.setIscollection(true);
            }
        }*/
        //2.2、判断是否点赞
        if (cacheService.hExists(userId + "_" + dto.getArticleId(), "operation")) {
            //存在则点赞了
            articleBehaviorVo.setIslike(true);
        }
        //2.3、判断是否点了不喜欢
        if (cacheService.hExists(userId + "_" + dto.getArticleId(), "unlike")) {
            //存在则是不喜欢
            articleBehaviorVo.setIsunlike(true);
        }
        //2.4、判断是否收藏
        if (cacheService.hExists(userId + "_" + dto.getArticleId(), "collection")) {
            articleBehaviorVo.setIscollection(true);
        }
        //2.5、判断是否关注
        List<Object> fans = (List<Object>) redisTemplate.opsForValue().get(dto.getAuthorId() + "_author");
        if (fans != null && fans.contains(userId)) {
            //粉丝列表存在则是关注了
            articleBehaviorVo.setIsfollow(true);
        }

        //3、返回响应结果
        return ResponseResult.okResult(articleBehaviorVo);
    }

    /**
     * 收藏亦或取消
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult collection(CollectionDto dto) {
        //1、参数校验
        if (dto == null || dto.getEntryId() == null || dto.getOperation() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、得到当前用户id
        Integer userId = AppUserThreadLocalUnit.get();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "未知错误，明明你在操作，却显示没有你这个人");
        }
        // 创建用户操作行为对象
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setArticleId(dto.getEntryId());
        mess.setType(UpdateArticleMess.UpdateArticleType.COLLECTION);
        //2.2、先获取该用户的对该文章的操作 以文章id+"_"+userId作为键,
        //redisTemplate.opsForValue().set(dto.getEntryId() + "_" + userId, dto.getOperation());
        if (dto.getOperation().equals(0)) {
            //收藏了
            cacheService.hPut(userId + "_" + dto.getEntryId(), "collection", dto.getOperation().toString());
            mess.setAdd(1);
        } else {
            //取消了
            cacheService.hDelete(userId + "_" + dto.getEntryId(), "collection");
            mess.setAdd(-1);
        }
        //往kafka发送消息 要使用kafkaStream流式计算
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));
        //3、返回响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
